/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.games.gpicalculator;

import it.polimi.games.epkb.controller.GpiKpiJpaController;
import it.polimi.games.epkb.controller.ObservedComponentJpaController;
import it.polimi.games.epkb.entityClasses.Component;
import it.polimi.games.epkb.entityClasses.GpiKpi;
import it.polimi.games.gpicalculator.jms.JMSConnection;
import it.polimi.games.gpicalculator.jms.JMSConnectionFactory;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

/**
 *
 * @author plebani
 */
public class GpiCalculatorThread extends Thread {

    private boolean running = false;
    private long frequency;
    private GpiKpi indicator;
    private GpiCalculator gpiCalculator;
    private Component component;
    EntityManagerFactory emfEpkb;
    
    

    public GpiCalculatorThread(GpiKpi indicator, GpiCalculator gpiCalculator, EntityManagerFactory emfEpkb) {

        super();


        this.indicator = indicator;
        this.frequency = indicator.getUpdateFrequency().longValue();
        this.gpiCalculator = gpiCalculator;
        this.component = component;

        this.emfEpkb = emfEpkb;
        



    }

    public boolean isRunning() {

        return this.running;
    }

    public void run() {

        try {

            this.running = true;

            ObservedComponentJpaController ocC = new ObservedComponentJpaController(emfEpkb);
            GpiKpiJpaController gpiKpiC = new GpiKpiJpaController(emfEpkb);

            Query q1 = ocC.getEntityManager().createQuery("SELECT DISTINCT s.idComponent FROM GpiKpiInstance s WHERE s.idGPIKPI=?1");
            q1.setParameter(1, gpiKpiC.findGpiKpi(indicator.getId()));

            Collection<Component> components = q1.getResultList();

            do {

                for (Component component : components) {

                    Logger.getLogger(GpiCalculatorThread.class.getName()).log(Level.INFO, "Calculating " + indicator.getName() + " on " + component.getId());
                    gpiCalculator.calculateGpi(indicator.getId(), component.getId());
                    Logger.getLogger(GpiCalculatorThread.class.getName()).log(Level.INFO, "Calculated " + indicator.getName() + " on " + component.getId());

                    //notify to the rest of the platform

                    try {

                       JMSConnection jc = JMSConnectionFactory.getJMSConnection();

                       jc.sendJMSMessage(indicator.getId(), component.getId());
                    } catch (Exception ex) {
                        Logger.getLogger(GpiCalculator.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
                    } finally {
                    }

                }

                try {
                    sleep(this.frequency * 1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(GpiCalculatorThread.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
                }
            } while (running);

        } catch (Exception ex) {
            Logger.getLogger(GpiCalculatorThread.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
        }
    }

    public void done() {

        this.running = false;
        gpiCalculator.closeGpiCalculator();
        this.emfEpkb.close();
    }
}
